package server.control;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.log4j.Logger;

import server.db.CreateTable;
import server.db.UserInteraction;
import server.jsons.User;

public class Control implements ServletContextListener {

	private static Logger logger = Logger.getLogger(Control.class.getName());
	private static Control myControl = null;

	private HashMap<String, User> validSessions = null;
	
	public static final String TODAY = "today";
	public static final String TOMORROW = "tomorrow";
	public static final String YESTERDAY = "yesterday";

	public Control() {
		validSessions = new HashMap<String, User>();
	}

	public static Control getInstance() {
		if (myControl == null) {
			myControl = new Control();
		}

		return myControl;
	}

	public boolean registerUser(User u) {
		if (u.getFirstname() != null && u.getSurname() != null
				&& u.getUserEmail() != null && u.getUserPwd() != null) {

			logger.info("Request to register User " + u.getUserEmail());

			if (UserInteraction.isRegisteredUser(u.getUserEmail())) {
				logger.info("User with " + u.getUserEmail()
						+ " already exists.");
				return false;
			} else if (u.getUserEmail() != null && u.getUserPwd() != null
					&& u.getSurname() != null && u.getFirstname() != null) {
				boolean success;
				success = UserInteraction.registerNewUser(u.getSurname(),
						u.getFirstname(), u.getUserEmail(), u.getUserPwd());
				logger.info("User " + u.getUserEmail() + " registered.");
				return success;
			} else {
				return false;
			}
		} else {
			return false;
		}

	}

	public boolean loginUser(User u) {
		u.setUserId(UserInteraction.loginUser(u.getUserEmail(), u.getUserPwd()));
		if (!this.validSessions.containsKey(u.getSessionId())) {
			if (u.getSessionId() == null) {
				if(u.getUserId() != "-1"){
					u.generateSessionID();
					this.validSessions.put(u.getSessionId(), u);
					logger.info("User " + u.getUserEmail() + " logged in.");
					return true;
				}else{
					logger.info("User " + u.getUserEmail() + " failed to log in.");
					return false;
				}
			}else{
				logger.info("User " + u.getUserEmail() + " failed to log in.");
				return false;
			}
		} else {
			u = this.validSessions.get(u.getSessionId());
			logger.info("User " + u.getUserEmail() + " already logged in.");
			return true;
		}

	}
	
	/**
	 * Returns a user only if the user has been logged in though
	 * @param sessionId
	 * @return
	 */
	public User getUser(String sessionId){
		return this.validSessions.get(sessionId);
	}

	public boolean logoutUser(User u) {
		if (this.validSessions.containsKey(u.getSessionId())) {
			this.validSessions.remove(u.getSessionId());
			logger.info("User " + u.getUserEmail() + " logged out.");
			return true;
		} else {
			logger.info("User " + u.getUserEmail()
					+ " logged out without being logged in.");
			return false;
		}
	}

	@Override
	public void contextDestroyed(ServletContextEvent arg0) {

	}

	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		int version = CreateTable.getVersion();
		try{
			while (Settings.dbCurrentVersion > version) {
				version = CreateTable.updateTables(version);
			}
		}catch (Exception e){
			logger.warn(e);
		}
		logger.info("Startup successfull.");
		logger.info("DatabaseVersion: " + version);

	}
	
	public String getDateYesterday(){
	    Calendar c = new GregorianCalendar();
	    c.set(Calendar.HOUR_OF_DAY, 0); //anything 0 - 23
	    c.set(Calendar.MINUTE, 0);
	    c.set(Calendar.SECOND, 0);
	    c.add(Calendar.DATE, -1);
	    
		SimpleDateFormat f = new SimpleDateFormat();
		f.applyPattern("yyyy-MM-dd HH:mm:ss");
	    
	    return f.format(c.getTime());
	}
	
	public String getDateToday(){
	    Calendar c = new GregorianCalendar();
	    c.set(Calendar.HOUR_OF_DAY, 0); //anything 0 - 23
	    c.set(Calendar.MINUTE, 0);
	    c.set(Calendar.SECOND, 0);
	    
		SimpleDateFormat f = new SimpleDateFormat();
		f.applyPattern("yyyy-MM-dd HH:mm:ss");
	    
	    return f.format(c.getTime());
	}
	

}
